package test.org.offsync.util

import org.junit.Test
import org.offsync.util.Disposer
import org.offsync.util.DisposableBase
import org.junit.Assert._

class TestDisposable {
  @Test def dispose_00(): Unit = {
    var counter = 0
    val disposer = new Disposer()
    val resource1 = disposer.disposes(new DisposableBase() {
      counter += 1
      
      override def onDispose(): Unit = {
        counter -= 1
        super.onDispose()
      }
    })
    
    assertEquals(1, counter)
    disposer.dispose()
    assertEquals(0, counter)
  }

  @Test def dispose_01(): Unit = {
    var counter = 0
    val disposer = new Disposer()
    val resource1 = disposer.disposes(new DisposableBase() {
      counter += 1
      
      override def onDispose(): Unit = {
        counter -= 1
        super.onDispose()
      }
    })
    
    assertEquals(counter, 1)
    val resource2 = disposer.disposes(new DisposableBase() {
      counter += 1
      
      override def onDispose(): Unit = {
        counter -= 1
        super.onDispose()
      }
    })
    
    assertEquals(counter, 2)
    disposer.dispose()
    assertEquals(counter, 0)
  }

  @Test def dispose_02(): Unit = {
    var counter = 0
    val disposer = new Disposer()
    val resource1 = disposer.disposes(new DisposableBase() {
      counter += 1
      
      override def onDispose(): Unit = {
        counter -= 1
        super.onDispose()
      }
    })
    
    assertEquals(counter, 1)
    try {
      val resource2 = try {
        disposer.disposes(new DisposableBase() {
          throw new Exception()
        })
      } catch { case e =>
        assertEquals(counter, 0)
        throw e
      }
      fail("exception should have been thrown")
    } catch { case e: Exception =>
      assertEquals(counter, 0)
    }
  }

  @Test def dispose_03(): Unit = {
    var counter = 0
    val disposer = new Disposer()
    
    val resource1 = disposer.disposes(new DisposableBase() {
      counter += 1
      
      override def onDispose(): Unit = {
        counter -= 1
        super.onDispose()
      }
    })
    assertEquals(counter, 1)
    
    val resource2 = disposer.disposes(new DisposableBase() {
      counter += 2
      
      override def onDispose(): Unit = {
        counter -= 2
        super.onDispose()
      }
    })
    assertEquals(counter, 3)
    
    try {
      val resource3 = try {
        disposer.disposes(new DisposableBase() {
          throw new Exception()
        })
      } catch { case e =>
        assertEquals(counter, 0)
        throw e
      }
      fail("exception should have been thrown")
    } catch { case e: Exception =>
      assertEquals(counter, 0)
    }
  }
}
